perm filename VISION.AL[AL,HE]1 blob sn#530425 filedate 1980-08-18 generic text, type C, neo UTF8
COMMENT ⊗   VALID 00003 PAGES
C REC  PAGE   DESCRIPTION
C00001 00001
C00002 00002	{Routines to call the Vision Module and have it do it's thing.
C00018 00003	{Definitions of feature numbers: }
C00023 ENDMK
C⊗;
{Routines to call the Vision Module and have it do it's thing.
 For more details see VM.DOC & COMM.TXT ON [DOC,HE]}

SCALAR VM_STATUS;

{Definitions of status values: }

DEFINE	OK =⊂0⊃;		{Successful}
DEFINE	NYI = ⊂1⊃;		{"Not Yet Implemented"}
DEFINE	BadCmnd = ⊂3⊃;		{CmnNum out of range}
DEFINE	OutOfRange = ⊂5⊃;	{Argument too low or too high}
DEFINE	ReservedCommand = ⊂7⊃;	{Command number reserved for future use}
DEFINE	NotFound = ⊂9⊃;		{Blob is not on active blobs list}
DEFINE	BadBlob = ⊂11⊃;		{Blob specification is illegal}
DEFINE	NoBlob = ⊂13⊃;		{Active blobs list is empty}
DEFINE	BadFeatNum = ⊂15⊃;	{Illegal feature number}
DEFINE	BadName = ⊂17⊃;		{Name not recognized from table}
DEFINE	Duplicate = ⊂19⊃;	{New name same as old name (prototypes)}
DEFINE	BadRestartOption = ⊂21⊃;	{Option NEQ 0 or 8 for Restart}
DEFINE	RestartAbort = ⊂23⊃;	{Vision System restarted during command}

SCALAR PROCEDURE InitVision;
   {Initialize communications software.  This routine must be called before
	 any other routines can be invoked.}
   BEGIN
   PROMPT("Is Vision Module running & is external-computer-control on? ");
   VM_STATUS ← VM(0,1,0,0,0);
   RETURN(VM_STATUS);
   END;

SCALAR PROCEDURE Restart (VALUE SCALAR how);
   {Restart the Vision System.  Either hard or soft restart can be selected.}
   BEGIN	{how = 0 for hard restart, ≠ 0 for soft restart}
   IF how THEN how ← 8.0;
   VM_STATUS ← VM(1,1,0,how,0);
   RETURN(VM_STATUS);
   END;

SCALAR PROCEDURE Picture (REFERENCE SCALAR numblobs);
   {Read a camera image into the image buffer and process it according to the
	 currently set parameters.}
   BEGIN
   VM_STATUS ← VM(2,0,1,0,numblobs);
   RETURN(VM_STATUS);
   END;

SCALAR PROCEDURE RePicture (REFERENCE SCALAR numblobs);
   {Reprocess the current image buffer using the currently set parameters.}
   BEGIN
   VM_STATUS ← VM(3,0,1,0,numblobs);
   RETURN(VM_STATUS);
   END;

SCALAR PROCEDURE GetFeature (VALUE SCALAR blobnum, idnum; REFERENCE SCALAR valu);
   {Return the value of one or more blob features. See next page for list of
	selectable features.}
   BEGIN
   VM_STATUS ← VM(4,2,0,blobnum,0,idnum,1,6,valu);
   RETURN(VM_STATUS);
   END;

SCALAR PROCEDURE Blink (VALUE SCALAR blobnum, color);
   {"Blink" the specified blob (Draw a line around the perimeter).
	  The outline can be either bright or dark.}
   BEGIN
   IF color THEN color ← -1;
   VM_STATUS ← VM(5,2,0,blobnum,0,color,0);
   RETURN(VM_STATUS);
   END;

SCALAR PROCEDURE DelBlob (VALUE SCALAR blobnum);
   {Delete a blob from the blob list.  This removes the blob descriptor from 
	free storage.  If the blob was previously "blinked", it is "unblinked"
	by drawing a dark line over its outline.}
   BEGIN
   VM_STATUS ← VM(6,1,0,blobnum,0);
   RETURN(VM_STATUS);
   END;

SCALAR PROCEDURE Calibrate (VALUE SCALAR blobnum);
   {Calibrate the various scale factors in the Vision System.  The specified 
	blob is used to calculate the size of pixels and the origin of the 
	Vision System coordinate system.  The calibration blob must be round
	and its size must have been previously specified as the value of the 
	variable "CALIBRATION SIZE".}
   BEGIN
   VM_STATUS ← VM(7,1,0,blobnum,0);
   RETURN(VM_STATUS);
   END;

SCALAR PROCEDURE Remember (VALUE SCALAR proid; VALUE STRING name);
   {Create an empty prototype descriptor in the Vision System and optionally 
	give it a name.}
   BEGIN
   VM_STATUS ← VM(8,2,0,proid,4,name,0);
   RETURN(VM_STATUS);
   END;

SCALAR PROCEDURE Train (VALUE SCALAR blobnum, proid);
   {Add the features of a specified blob into the specified prototype.  Both the 
	mean and the variance about the mean are calculated for those features
	which can be used for recognition.}
   BEGIN
   VM_STATUS ← VM(9,2,0,blobnum,0,proid,0);
   RETURN(VM_STATUS);
   END;

SCALAR PROCEDURE Recognize (VALUE SCALAR blobnum; REFERENCE SCALAR proid, d1, d2);
   {Identify which prototype is closest to the specified blob.  All prototypes 
	known to the system are compared to the specified blob and the closest 
	one is identified and its "distance" from the blob is calculated.}
   BEGIN
   VM_STATUS ← VM(10,1,0,blobnum,3,0,proid,2,d1,2,d2);
   RETURN(VM_STATUS);
   END;

SCALAR PROCEDURE WhereAre (VALUE SCALAR proid, matches, newpic;
						SCALAR ARRAY vals[1:5,1:5]);
   {Identify all blobs which are acceptably close to the specified prototype.
	A list of their identities and information about them is returned.}
   BEGIN
   SCALAR b1,b2,b3,b4,b5; {Temporary storage}
   SCALAR d1,d2,d3,d4,d5;
   SCALAR x1,x2,x3,x4,x5;
   SCALAR y1,y2,y3,y4,y5;
   SCALAR o1,o2,o3,o4,o5;

   IF newpic > 0 THEN newpic ← 1 ELSE IF newpic < 0 THEN newpic ← -1;

   CASE matches OF BEGIN
[0]	BEGIN
	PRINT(crlf,"WhereAre: max number of matches must be at least 1",crlf);
	VM_STATUS ← OutOfRange;
	RETURN(VM_STATUS);
	END;
[1]	VM_STATUS ← VM(11,3,0,proid,0,1,0,newpic,5,0,b1,2,d1,2,x1,2,y1,2,o1);
[2]	VM_STATUS ← VM(11,3,0,proid,0,2,0,newpic,10,0,b1,2,d1,2,x1,2,y1,2,o1,
						    0,b2,2,d2,2,x2,2,y2,2,o2);
[3]	VM_STATUS ← VM(11,3,0,proid,0,3,0,newpic,15,0,b1,2,d1,2,x1,2,y1,2,o1,
			   0,b2,2,d2,2,x2,2,y2,2,o2,0,b3,2,d3,2,x3,2,y3,2,o3);
[4]	VM_STATUS ← VM(11,3,0,proid,0,4,0,newpic,20,0,b1,2,d1,2,x1,2,y1,2,o1,
			   0,b2,2,d2,2,x2,2,y2,2,o2,0,b3,2,d3,2,x3,2,y3,2,o3,
						    0,b4,2,d4,2,x4,2,y4,2,o4);
ELSE	VM_STATUS ← VM(11,3,0,proid,0,5,0,newpic,25,0,b1,2,d1,2,x1,2,y1,2,o1,
			   0,b2,2,d2,2,x2,2,y2,2,o2,0,b3,2,d3,2,x3,2,y3,2,o3,
			   0,b4,2,d4,2,x4,2,y4,2,o4,0,b5,2,d5,2,x5,2,y5,2,o5)
   END;

   vals[1,1]←b1; vals[1,2]←d1; vals[1,3]←x1; vals[1,4]←y1; vals[1,5]←o1;
   IF matches > 1 THEN
	BEGIN
	vals[2,1]←b2; vals[2,2]←d2; vals[2,3]←x2; vals[2,4]←y2; vals[2,5]←o2;
	END;
   IF matches > 2 THEN
	BEGIN
	vals[3,1]←b3; vals[3,2]←d3; vals[3,3]←x3; vals[3,4]←y3; vals[3,5]←o3;
	END;
   IF matches > 3 THEN
	BEGIN
	vals[4,1]←b4; vals[4,2]←d4; vals[4,3]←x4; vals[4,4]←y4; vals[4,5]←o4;
	END;
   IF matches > 4 THEN
	BEGIN
	vals[5,1]←b5; vals[5,2]←d5; vals[5,3]←x5; vals[5,4]←y5; vals[5,5]←o5;
	END;
   IF matches > 5 THEN
	PRINT(crlf,"WhereAre: max number of matches can't be > 5",crlf);

   RETURN(VM_STATUS);
   END;

SCALAR PROCEDURE WhereIs (VALUE SCALAR proid, newpic;
			REFERENCE SCALAR blobnum, dis, x, y, ori);
   {Special case of WhereAre. Identifies one blob which is acceptably close 
	to the specified prototype. Information about it is returned.}
   BEGIN
   IF newpic > 0 THEN newpic ← 1 ELSE IF newpic < 0 THEN newpic ← -1;
   VM_STATUS ← VM(11,3,0,proid,0,1,0,newpic,5,0,blobnum,2,dis,2,x,2,y,2,ori);
   RETURN(VM_STATUS);
   END;

SCALAR PROCEDURE Forget (VALUE SCALAR proid);
   {Delete a prototype descriptor from the Vision System.}
   BEGIN
   VM_STATUS ← VM(12,1,0,proid,0);
   RETURN(VM_STATUS);
   END;

SCALAR PROCEDURE SRead (STRING name; REFERENCE SCALAR valu);
   {Return the value of a switch.  The value will be 0 if the switch is off,
	and -1 if the switch is on.}
   BEGIN
   VM_STATUS ← VM(13,1,4,name,1,0,valu);
   RETURN(VM_STATUS);
   END;

SCALAR PROCEDURE SWrite (STRING name; SCALAR valu);
   {Write the value of a switch.  The value should be 0 to turn the switch off,
	and -1 to turn it on.}
   BEGIN
   IF valu THEN valu ← -1;
   VM_STATUS ← VM(14,2,0,valu,4,name,0);
   RETURN(VM_STATUS);
   END;

SCALAR PROCEDURE VRead (STRING name; REFERENCE SCALAR valu);
   {Read the value of a variable.}
   BEGIN
   VM_STATUS ← VM(15,1,4,name,1,2,valu);
   RETURN(VM_STATUS);
   END;

SCALAR PROCEDURE VWrite (STRING name; SCALAR valu);
   {Write the value of a variable.}
   BEGIN
   VM_STATUS ← VM(16,2,2,valu,4,name,0);
   RETURN(VM_STATUS);
   END;

SCALAR PROCEDURE Erase;
   {Erase graphics overlay.}
   BEGIN
   VM_STATUS ← VM(24,1,0,0,0);
   RETURN(VM_STATUS);
   END;

SCALAR PROCEDURE ClearW (VALUE SCALAR x, y, dx, dy, color);
   {Clear a rectangular area in graphics overlay.}
   BEGIN
   IF color THEN color ← -1;
   VM_STATUS ← VM(25,5,0,x,0,y,0,dx,0,dy,0,color,0);
   RETURN(VM_STATUS);
   END;

SCALAR PROCEDURE Draw (VALUE SCALAR x, y, dx, dy, color);
   {Draw a vector on the display.  The vector can be either bright or dark.}
   BEGIN
   IF color THEN color ← -1;
   VM_STATUS ← VM(26,5,0,x,0,y,0,dx,0,dy,0,color,0);
   RETURN(VM_STATUS);
   END;

SCALAR PROCEDURE DText (VALUE SCALAR x, y; VALUE STRING text;
						REFERENCE SCALAR nx, ny);
   {Display a text string on the display. The characters will always be bright.}
   BEGIN
   VM_STATUS ← VM(27,3,0,x,0,y,4,text,2,0,nx,0,ny);
   RETURN(VM_STATUS);
   END;

SCALAR PROCEDURE ProRead (VALUE SCALAR proid; SCALAR ARRAY des[1:144]);
   {Read the contents of a prototype descriptor from the Vision System.
	This is currently a core image of the prototype. For now, it is
	intended for saving and restoring the prototypes only.}
   BEGIN
   PRINT(crlf,"Read Prototype not implemented",crlf);
   VM_STATUS ← NYI; {Not Yet Implemented}
   RETURN(VM_STATUS);
   END;

SCALAR PROCEDURE ProWrite (SCALAR ARRAY des[1:144]);
   {Write a prototype descriptor to the Vision System. 	The format should be 
	identical to that previously read from the Vision System by ProRead.}
   BEGIN
   PRINT(crlf,"Write Prototype not implemented",crlf);
   VM_STATUS ← NYI; {Not Yet Implemented}
   RETURN(VM_STATUS);
   END;

SCALAR PROCEDURE PicRead (VALUE SCALAR rasnum; SCALAR ARRAY data[1:16]);
   {Read the contents of one row of the currently selected image buffer.}
   BEGIN rasnum←1; {to avoid parser warning}
   PRINT(crlf,"Picture Read not implemented",crlf);
   VM_STATUS ← NYI; {Not Yet Implemented}
   RETURN(VM_STATUS);
   END;

SCALAR PROCEDURE PicWrite (VALUE SCALAR rasnum; SCALAR ARRAY data[1:16]);
   {This writes one row in the currently selected image buffer.
	The format is the same as that returned by PicRead.}
   BEGIN rasnum←1; {to avoid parser warning}
   PRINT(crlf,"Picture Write not implemented",crlf);
   VM_STATUS ← NYI; {Not Yet Implemented}
   RETURN(VM_STATUS);
   END;

{Definitions of feature numbers: }

DEFINE	NEXT = ⊂0⊃;		{Link of all active blobs}
DEFINE	PARENT = ⊂2⊃;		{Address of parent blob}
DEFINE	BCOLOR = ⊂4⊃;		{0 if black, -1 if white}
DEFINE	NCELLS = ⊂8⊃;		{Area in pixels}
DEFINE	PerimOn = ⊂10⊃;		{Perimeter list intensified on display}
DEFINE	TOTALCELLS = ⊂12⊃;	{Area in pixels, including holes}
DEFINE	EBOUNDARY = ⊂14⊃;	{Pointer to end of boundary list}
DEFINE	NHOLES = ⊂16⊃;		{Number of holes in the blob}
DEFINE	BOUNDARY = ⊂18⊃;	{Pointer to start of boundary list}
DEFINE	XMIN = ⊂20⊃;		{Minimum X (relative to XBASE)}
DEFINE	NBSEG = ⊂22⊃;		{Number of boundary segments}
DEFINE	XMAX = ⊂24⊃;		{Maximum X (relative to XBASE)}
DEFINE	NBCELLS = ⊂26⊃;		{Total perimeter length = XPERIM+YPERIM}
DEFINE	YMIN = ⊂28⊃;		{Minimum Y (relative to YBASE)}
DEFINE	MODEL = ⊂30⊃;		{Pointer to matching prototype}
DEFINE	YMAX = ⊂32⊃;		{Maximum Y (relative to YBASE)}
DEFINE	EXLINK = ⊂34⊃;		{Extra word for list links}
DEFINE	XPERIM = ⊂36⊃;		{Perimeter length in X-direction}
DEFINE	RMINI = ⊂38⊃;		{Index of minimum radius point}
DEFINE	YPERIM = ⊂40⊃;		{Perimeter length in Y-direction}
DEFINE	RMAXI = ⊂42⊃;		{Index of maximum radius point}

DEFINE	SIGX = ⊂44⊃;		{Sigma X for the blob (relative to XBASE)}
DEFINE	SIGY = ⊂48⊃;		{Ditto Y (relative to YBASE)}
DEFINE	SIGXX = ⊂52⊃;		{Sigma X squared, times 12}
DEFINE	SIGXY = ⊂56⊃;		{Sigma X times Y, times 2}
DEFINE	SIGYY = ⊂60⊃;		{Sigma Y squared}

DEFINE	AREA = ⊂64⊃;		{Area in calibrated units}
DEFINE	XCENT = ⊂68⊃;		{X centroid (relative to calibrated center)}
DEFINE	YCENT = ⊂72⊃;		{Ycentroid (relative to calibrated center)}
DEFINE	MAJOR = ⊂76⊃;		{Length of major axis of best ellipse}
DEFINE	MINOR = ⊂80⊃;		{Length of minor axis of best ellipse}
DEFINE	THETA = ⊂84⊃;		{Angle of major axis of best ellipse}
DEFINE	PERIMETER = ⊂88⊃;	{Perimeter length}
DEFINE	TOTALAREA = ⊂92⊃;	{Area + hole area}
DEFINE	RMIN = ⊂96⊃;		{Min (perim-cg)**2}
DEFINE	RMAX = ⊂100⊃;		{Max of same}
DEFINE	RMINANG = ⊂104⊃;	{Angle of minimum radius vector}
DEFINE	RMAXANG = ⊂108⊃;	{Angle of maximum radius vector}
DEFINE	AVRAD = ⊂112⊃;		{Avg (perim-cg)**2 for all perim points}
DEFINE	LENGTH = ⊂116⊃;		{Dimensions of a bounding box}
DEFINE	WIDTH = ⊂120⊃;		{  aligned with theta}
DEFINE	ORIENTATION = ⊂124⊃;	{Orientation of object (unambiguous)}

DEFINE	HOLEAREA = ⊂128⊃;	{Area of holes (and their holes, etc)}
DEFINE	HOLERATIO = ⊂132⊃;	{Ratio of hole area to total area}
DEFINE	AXRATIO = ⊂136⊃;	{MINOR / MAJOR}
DEFINE	PSQUARED = ⊂140⊃;	{PERIMETER squared}
DEFINE	PPDA = ⊂144⊃;		{PSQUARED / AREA}
DEFINE	RADRATIO = ⊂148⊃;	{RMIN / RMAX}
DEFINE	LENRATIO = ⊂152⊃;	{WIDTH / LENTH}
DEFINE	YDIFF1 = ⊂156⊃;
DEFINE	YDIFF = ⊂160⊃;		{Y-Height}
DEFINE	XDIFF1 = ⊂164⊃;
DEFINE	XDIFF = ⊂168⊃;		{X-Width}
DEFINE	BOXAREA = ⊂172⊃;	{XDIFF * YDIFF}
DEFINE	BXARATIO = ⊂176⊃;	{BOXAREA / TOTALAREA}
DEFINE	XCENT2 = ⊂180⊃;
DEFINE	YCENT2 = ⊂184⊃;
DEFINE	CGDIST = ⊂188⊃;		{XCENT squared + YCENT squared}
DEFINE	PEROU1 = ⊂192⊃;
DEFINE	PEROUND = ⊂196⊃;	{4 * PI * AREA / PSQUARED}
DEFINE	ANGMOD = ⊂200⊃;		{RMAXANG - RMINANG (+-PI range)}